home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / XLIB06.ZIP / XCLIPPBM.ASM < prev    next >
Assembly Source File  |  1993-09-13  |  13KB  |  508 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XCLIPPBM
  3. ;
  4. ; This module was written by Matthew MacKenzie
  5. ; matm@eng.umd.edu
  6. ;
  7. ; Clipped transfer of planar bitmaps from system memory to video memory.
  8. ;
  9. ; Compile with TASM.
  10. ; C near-callable.
  11. ;
  12. ; ****** XLIB - Mode X graphics library                ****************
  13. ; ******                                               ****************
  14. ; ****** Written By Themie Gouthas                     ****************
  15. ;
  16. ; egg@dstos3.dsto.gov.au
  17. ; teg@bart.dsto.gov.au
  18. ;-----------------------------------------------------------------------
  19.  
  20. include xlib.inc
  21. include xclippbm.inc
  22.  
  23.  
  24.     .data
  25.  
  26.     align 2
  27.  
  28. ; global clipping variables
  29. _TopBound       dw      (?)
  30. _BottomBound    dw      (?)
  31. _LeftBound      dw      (?)
  32. _RightBound     dw      (?)
  33.  
  34. ; VGA plane masks
  35. ColumnMask      db      011h,022h,044h,088h
  36.  
  37. ; bit delay timers
  38. LeftDelay       db      0, 1, 2, 4
  39. RightDelay      db      0, 4, 2, 1
  40.  
  41.  
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. ; _x_clip_pbm
  44. ;
  45. ; C near-callable as:
  46. ;
  47. ; void x_clip_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  48. ;
  49. ; Bitmap is a planar bitmap, in the regular Xlib format.
  50. ;
  51. ; ax, bx, cx, and dx go south.
  52.  
  53.     .code
  54.  
  55.     public _x_clip_pbm
  56.     align   2
  57. _x_clip_pbm proc
  58. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  59. LOCAL   left_counter, right_counter,column,clipped_height,clipped_width,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk
  60. ; Tasm 1.0 does not allow the \ line continuation
  61. ;LOCAL   left_counter:word, right_counter:word, \
  62. ;        column:word, clipped_height:word, clipped_width:word, \
  63. ;        screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  64. ;        VGA_mask:word, width_copy, height_temp:word, \
  65. ;        screen_width:word=LocalStk
  66.  
  67.     push bp
  68.     mov bp, sp
  69.     sub sp, LocalStk
  70.     push si
  71.     push di
  72.     push ds
  73.  
  74. ; sociopathic cases: are the clipping bounds out of order?
  75.     mov ax, _TopBound
  76.     cmp ax, _BottomBound
  77.     jg @@GetOut
  78.     mov ax, _LeftBound
  79.     cmp ax, _RightBound
  80.     jle @@ReasonableAndProper
  81. @@GetOut:                ; return a 1 -- no image drawn
  82.     pop ds
  83.     pop di
  84.     pop si
  85.     mov ax, 1
  86.     mov sp, bp
  87.     pop bp
  88.     ret
  89.  
  90. @@ReasonableAndProper:
  91.  
  92. ; we need to use both the tables in ds and the height and width of the bitmap
  93.     les si, Bitmap
  94.  
  95. ; vertical position
  96.     xor cx, cx
  97.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  98.     xor ax, ax
  99.     mov al, byte ptr es:[si] ; width of bitmap
  100.     mul cx
  101.     mov bitmap_size, ax
  102.     mov ax, Y
  103.     cmp ax, _BottomBound ; top edge below clipping box?
  104.     jg @@GetOut
  105.  
  106.     mov bx, cx
  107.     add bx, ax
  108.     dec bx              ; bottom edge = Y + height - 1
  109.     cmp bx, _TopBound
  110.     jl @@GetOut
  111.     sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound
  112.     jle @@NoBottomBound
  113.     sub cx, bx          ; clip bottom margin from height
  114. @@NoBottomBound:
  115.     mov bx, _TopBound
  116.     sub bx, ax          ; top margin = TopBound - Y
  117.     jle @@NoTopBound
  118.     add ax, bx          ; top edge = Y + top margin
  119.     sub cx, bx          ; clip top margin from height
  120.     jmp @@KeepMargin
  121. @@NoTopBound:
  122.     xor bx, bx
  123. @@KeepMargin:
  124.     mov clipped_height, cx
  125.  
  126.     mul _ScrnLogicalByteWidth
  127.     mov di, ax
  128.     add di, ScreenOffs  ; row of upper-left corner of blit
  129.  
  130.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  131.     mov ax, cx
  132.     mul bx
  133.     add si, ax
  134.     add si, 2           ; starting position in bitmap
  135.  
  136. ; horizontal position
  137.     mov width_copy, cx
  138.     mov dx, X
  139.     cmp dx, _RightBound
  140.     jg @@GetOut
  141.     mov dx, 0           ; unclipped value for right delay
  142.  
  143.     mov ax, cx
  144.     shl ax, 2           ; width in pixels
  145.     add ax, X
  146.     dec ax              ; right edge = X + width in pixels - 1
  147.     cmp ax, _LeftBound
  148.     jl @@GetOut
  149.     sub ax, _RightBound  ; right margin = right edge - RightBound
  150.     jle @@NoRightBound
  151.     mov bx, ax
  152.     and bx, 3
  153.     mov dl, RightDelay[bx]
  154.     shr ax, 2
  155.     sub cx, ax          ; subtract clipped bytes from width
  156. @@NoRightBound:
  157.     mov right_counter, dx
  158.     mov dx, 0           ; unclipped value for left delay
  159.     mov ax, _LeftBound
  160.     sub ax, X           ; left margin = LeftBound - X
  161.     jle @@NoLeftBound
  162.     mov bx, ax
  163.     and bx, 3
  164.     mov dl, LeftDelay[bx]
  165.     add ax, 3
  166.     shr ax, 2           ; left margin/4, rounded up
  167.     sub cx, ax          ; subtract clipped bytes from width
  168.     add si, ax          ; move starting position in bitmap past margin
  169.     add di, ax          ; move starting position on screen past margin
  170. @@NoLeftBound:
  171.     mov left_counter, dx
  172.     mov clipped_width, cx
  173.  
  174.     mov ax, X           ; add x coordinate to screen position
  175.     mov bx, ax
  176.     sar ax, 2
  177.     add di, ax
  178.  
  179.     mov dx, SC_INDEX
  180.     mov al, MAP_MASK
  181.     out dx, al
  182.     inc dx
  183.  
  184.     and bx, 3           ; initial mask
  185.     xor ax, ax
  186.     mov al, ColumnMask[bx]
  187.     mov VGA_mask, ax
  188.     out dx, al          ; initial mask
  189.  
  190.     mov column, 4
  191.     mov bitmap_pos, si
  192.     mov screen_pos, di
  193.     mov ax, _ScrnLogicalByteWidth
  194.     mov screen_width, ax ; since we move ds
  195.  
  196. ; we've used all our tables, so we can change ds to point to the bitmap,
  197. ; and es to point to the screen
  198.     mov ds, word ptr [Bitmap + 2]
  199.     mov ax, SCREEN_SEG
  200.     mov es, ax
  201.  
  202.     cld                 ; strings go forward
  203.     mov bx, width_copy
  204.     sub bx, clipped_width ; bytes to advance one line in bitmap
  205.  
  206. ; let's actually draw something for a change
  207. @@WritePlane:
  208.     mov ax, clipped_height
  209.     mov height_temp, ax
  210.     mov dx, screen_width
  211.     sub dx, clipped_width ; bytes to advance one line across screen
  212.  
  213. @@WriteLine:
  214.     mov cx, clipped_width
  215.     shr cx, 1
  216.     rep movsw           ; in they went, two by two...
  217.     adc cx, 0
  218.     rep movsb           ; catch stray last byte, if it's there
  219.     add si, bx          ; advance one bitmap line
  220.     add di, dx          ; advance one screen line
  221.  
  222.     dec height_temp
  223.     jnz @@WriteLine
  224.  
  225.     dec column
  226.     jz @@OuttaHere      ; only four columns per customer, please
  227.     mov dx, SC_INDEX + 1
  228.     rol byte ptr VGA_mask, 1
  229.     adc screen_pos, 0   ; add to location if we've wrapped to plane 0
  230.     mov al, byte ptr VGA_mask
  231.     out dx, al          ; set VGA for next column
  232.  
  233.     shr right_counter, 1
  234.     jnc @@NoRightCounter
  235.     dec clipped_width   ; cut off right edge for later planes
  236.     inc bx
  237. @@NoRightCounter:
  238.     shr left_counter, 1
  239.     jnc @@NoLeftCounter
  240.     inc clipped_width   ; add to left edge for later planes
  241.     dec bx
  242.     dec bitmap_pos
  243.     dec screen_pos
  244. @@NoLeftCounter:
  245.     mov si, bitmap_pos
  246.     add si, bitmap_size
  247.     mov bitmap_pos, si
  248.     mov di, screen_pos
  249.     jmp @@WritePlane
  250.  
  251. @@OuttaHere:            ; return a 0 -- something was inside the boundary
  252.     pop ds
  253.     pop di
  254.     pop si
  255.     mov ax, 0
  256.     mov sp, bp
  257.     pop bp
  258.     ret
  259. _x_clip_pbm endp
  260.  
  261.  
  262. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  263. ; _x_clip_masked_pbm
  264. ;
  265. ; C near-callable as:
  266. ;
  267. ; void x_clip_masked_pbm (int X, int Y, int ScreenOffs, char far * Bitmap);
  268. ;
  269. ; Bitmap is a planar bitmap, in the regular Xlib format.
  270. ; The width of the bitmap cannot be greater than 90 bytes, however.
  271. ; Ain't that just criminal?
  272. ;
  273. ; ax, bx, cx, and dx go south.
  274.  
  275.  
  276. ; one branch per pixel is more than enough -- we'll unroll the line-writing
  277. ; loop all the way to try to get a little speed (at the expense, as usual,
  278. ; of a chunk of memory)
  279.  
  280. MaskedPoint macro offset
  281.     mov al, [si + offset]
  282.     or al, al
  283.     jz $+6
  284.     mov es:[di + offset], al
  285.     endm
  286.  
  287. MaskedPointSize     equ     11
  288.  
  289.     public _x_clip_masked_pbm
  290.     align   2
  291. _x_clip_masked_pbm proc
  292. ARG     X:word, Y:word, ScreenOffs:word, Bitmap:dword
  293. ; Tasm 1.0 does not allow the \ line continuation
  294. LOCAL   left_counter,right_counter,column:word,clipped_height,screen_pos,bitmap_pos,bitmap_size,VGA_mask,width_copy,height_temp,screen_width:word=LocalStk
  295. ;LOCAL   left_counter:word, right_counter:word, \
  296. ;        column:word, clipped_height:word, \
  297. ;        screen_pos:word, bitmap_pos:word, bitmap_size:word, \
  298. ;        VGA_mask:word, width_copy, height_temp:word, \
  299. ;        screen_width:word=LocalStk
  300.     push bp
  301.     mov bp, sp
  302.     sub sp, LocalStk
  303.     push si
  304.     push di
  305.     push ds
  306.  
  307. ; sociopathic cases: are the clipping bounds out of order?
  308.     mov ax, _TopBound
  309.     cmp ax, _BottomBound
  310.     jg @@GetOut
  311.     mov ax, _LeftBound
  312.     cmp ax, _RightBound
  313.     jle @@ReasonableAndProper
  314. @@GetOut:                ; return a 1 -- no image drawn
  315.     pop ds
  316.     pop di
  317.     pop si
  318.     mov ax, 1
  319.     mov sp, bp
  320.     pop bp
  321.     ret
  322.  
  323. @@ReasonableAndProper:
  324.  
  325. ; we need to use both the tables in ds and the height and width of the bitmap
  326.     les si, Bitmap
  327.  
  328. ; vertical position
  329.     xor cx, cx
  330.     mov cl, byte ptr es:[si + 1] ; height of bitmap
  331.     xor ax, ax
  332.     mov al, byte ptr es:[si] ; width of bitmap
  333.     mul cx
  334.     mov bitmap_size, ax
  335.     mov ax, Y
  336.     cmp ax, _BottomBound ; top edge below clipping box?
  337.     jg @@GetOut
  338.  
  339.     mov bx, cx
  340.     add bx, ax
  341.     dec bx              ; bottom edge = Y + height - 1
  342.     cmp bx, _TopBound
  343.     jl @@GetOut
  344.     sub bx, _BottomBound ; bottom margin = bottom edge - BottomBound
  345.     jle @@NoBottomBound
  346.     sub cx, bx          ; clip bottom margin from height
  347. @@NoBottomBound:
  348.     mov bx, _TopBound
  349.     sub bx, ax          ; top margin = TopBound - Y
  350.     jle @@NoTopBound
  351.     add ax, bx          ; top edge = Y + top margin
  352.     sub cx, bx          ; clip top margin from height
  353.     jmp @@KeepMargin
  354. @@NoTopBound:
  355.     xor bx, bx
  356. @@KeepMargin:
  357.     mov clipped_height, cx
  358.  
  359.     mul _ScrnLogicalByteWidth
  360.     mov di, ax
  361.     add di, ScreenOffs  ; row of upper-left corner of blit
  362.  
  363.     mov cl, byte ptr es:[si] ; width of bitmap (ch is still 0 from height)
  364.     mov ax, cx
  365.     mul bx
  366.     add si, ax
  367.     add si, 2           ; starting position in bitmap
  368.  
  369. ; horizontal position
  370.     mov width_copy, cx
  371.     mov dx, X
  372.     cmp dx, _RightBound
  373.     jg @@GetOut
  374.     mov dx, 0           ; unclipped value for right delay
  375.  
  376.     mov ax, cx
  377.     shl ax, 2           ; width in pixels
  378.     add ax, X
  379.     dec ax              ; right edge = X + width in pixels - 1
  380.     cmp ax, _LeftBound
  381.     jl @@GetOut
  382.     sub ax, _RightBound ; right margin = right edge - RightBound
  383.     jle @@NoRightBound
  384.     mov bx, ax
  385.     and bx, 3
  386.     mov dl, RightDelay[bx]
  387.     shr ax, 2
  388.     sub cx, ax          ; subtract clipped bytes from width
  389. @@NoRightBound:
  390.     mov right_counter, dx
  391.     mov dx, 0           ; unclipped value for left delay
  392.     mov ax, _LeftBound
  393.     sub ax, X           ; left margin = LeftBound - X
  394.     jle @@NoLeftBound
  395.     mov bx, ax
  396.     and bx, 3
  397.     mov dl, LeftDelay[bx]
  398.     add ax, 3
  399.     shr ax, 2           ; left margin/4, rounded up
  400.     sub cx, ax          ; subtract clipped bytes from width
  401.     add si, ax          ; move starting position in bitmap past margin
  402.     add di, ax          ; move starting position on screen past margin
  403. @@NoLeftBound:
  404.     mov left_counter, dx
  405.     mov ax, cx
  406.     imul ax, (-1 * MaskedPointSize)
  407.     add ax, offset @@LineDone + 2
  408.     mov cx, ax          ; jump offset for plotting
  409.  
  410.     mov ax, X           ; add x coordinate to screen position
  411.     mov bx, ax
  412.     shr ax, 2
  413.     add di, ax
  414.  
  415.     mov dx, SC_INDEX
  416.     mov al, MAP_MASK
  417.     out dx, al
  418.     inc dx
  419.  
  420.     and bx, 3           ; initial mask
  421.     xor ax, ax
  422.     mov al, ColumnMask[bx]
  423.     mov VGA_mask, ax
  424.     out dx, al
  425.  
  426.     mov column, 4
  427.     mov bitmap_pos, si
  428.     mov screen_pos, di
  429.     mov ax, _ScrnLogicalByteWidth
  430.     mov screen_width, ax ; since we move ds
  431.  
  432. ; we've used all our tables, so we can change ds to point to the bitmap,
  433. ; and es to point to the screen
  434.     mov ds, word ptr [Bitmap + 2]
  435.     mov ax, SCREEN_SEG
  436.     mov es, ax
  437.  
  438.     mov bx, width_copy
  439.  
  440. ; let's actually draw something for a change
  441.     mov ax, clipped_height
  442.     mov height_temp, ax
  443.     mov dx, screen_width
  444.     jmp cx
  445.  
  446. ; 90 bottles of beer on the wall...
  447.     PointLoop = 89
  448.     rept 89
  449.         MaskedPoint PointLoop
  450.         PointLoop = PointLoop - 1
  451.     endm
  452. ; one bottle of beer...
  453.  
  454. ; final point needs a different branch offset, so we don't use MaskedPoint
  455.     mov al, [si]
  456.     or al, al
  457.     jz @@LineDone
  458.     mov es:[di], al
  459.  
  460. @@LineDone:
  461.     add si, bx          ; advance one bitmap line
  462.     add di, dx          ; advance one screen line
  463.     dec height_temp
  464.     jz @@PlaneDone
  465.     jmp cx
  466.  
  467. @@PlaneDone:
  468.     dec column
  469.     jz @@OuttaHere      ; only four columns per customer, please
  470.     mov dx, SC_INDEX + 1
  471.     rol byte ptr VGA_mask, 1
  472.     adc screen_pos, 0   ; move to new column if we've wrapped to plane 0
  473.     mov al, byte ptr VGA_mask
  474.     out dx, al          ; set VGA for next column
  475.  
  476.     shr right_counter, 1
  477.     jnc @@NoRightCounter
  478.     add cx, MaskedPointSize ; cut off right edge for later planes
  479. @@NoRightCounter:
  480.     shr left_counter, 1
  481.     jnc @@NoLeftCounter
  482.     sub cx, MaskedPointSize ; add to left edge for later planes
  483.     dec bitmap_pos
  484.     dec screen_pos
  485. @@NoLeftCounter:
  486.     mov si, bitmap_pos
  487.     add si, bitmap_size
  488.     mov bitmap_pos, si
  489.     mov di, screen_pos
  490.  
  491.     mov ax, clipped_height
  492.     mov height_temp, ax
  493.     mov dx, screen_width
  494.     jmp cx
  495.  
  496. @@OuttaHere:            ; return a 0 -- something was inside the boundary
  497.     pop ds
  498.     pop di
  499.     pop si
  500.     mov ax, 0
  501.     mov sp, bp
  502.     pop bp
  503.     ret
  504. _x_clip_masked_pbm endp
  505.  
  506.     end
  507.  
  508.